call testFormantMethods

##################
# test formant methods
##################
procedure testFormantMethods

	.ft = Create formant table (Pols & Van Nierop 1973)
	.pols = Collapse rows... "Sex IPA" "" "F1 F2 F3" "" ""
	.rows = Get number of rows

	select .ft
	Remove

	# create result table
	.restab = Create Table with column names... results 0 Sex NrFormants IPA F1in F2in F3in SourceHz RobustStd Bandwidth Type MaxFreq F1b F2b F3b B1b B2b B3b F1r F2r F3r B1r B2r B3r

	for .row from 1 to .rows 
		#.rows
		#.row = 2
		# get values for vowel generation
		select .pols
		.vF1 = Get value... .row F1
		.vF2 = Get value... .row F2
		.vF3 = Get value... .row F3
		.vF4 = 3500
		.vF5 = 4500	
		.sex$ = Get value... .row Sex
		.ipa$ = Get value... .row IPA

		printline generating vowel '.sex$' '.ipa$'

		#set the maximum frequency from 4500 to 6000 in steps of 250
		for .tmp_maxfreq from 0 to 2
			.maxfreq = 4500 + .tmp_maxfreq * 500

			#vowel source frequency from 50 to 350 in steps of 50
			for .tmp_srcHz  from 0 to 2
				.srcHz = 100 + .tmp_srcHz * 100

				#select the number of formants to use			
				#for .nrformants from 3 to 5
				.nrformants = 5
					# input bandwidth from 8% to 20%
					for .tmp_bw from 0 to 4
						.bw = 0.08 + .tmp_bw * 0.03

						#select the type of vowel creation (pulse train / phonation) 
						for .type from 0 to 1

							#create the vowel with the selected features
							call createVowel .type .nrformants .srcHz .vF1 '.vF1'*'.bw' .vF2 '.vF2'*'.bw' .vF3 '.vF3'*'.bw' .vF4 .vF5

							# burg analyzation
							call analyzeFormants createVowel.id .maxfreq 0 0.1 0.2
							.tmp_res[1] = analyzeFormants.res[1]
							.tmp_res[2] = analyzeFormants.res[2]
							.tmp_res[3] = analyzeFormants.res[3]
							.tmp_res[4] = analyzeFormants.res[4]
							.tmp_res[5] = analyzeFormants.res[5]
							.tmp_res[6] = analyzeFormants.res[6]

							#test std from 1 to 2.5 in steps of 0.25
							#for .tmp_std from 0 to 6
								#.std = 1 + .tmp_std * 0.25
								.std = 1.5

								# robust analyzation
								call analyzeFormants createVowel.id .maxfreq .std 0.1 0.2

								#write away results		
								select .restab
								Append row
								.i = Get number of rows
								Set numeric value... .i NrFormants .nrformants
								Set numeric value... .i F1in .vF1
								Set numeric value... .i F2in .vF2
								Set numeric value... .i F3in .vF3
								Set string value... .i Sex '.sex$'
								Set string value... .i IPA '.ipa$'
								Set numeric value... .i Type .type
								Set numeric value... .i SourceHz .srcHz
								Set numeric value... .i Bandwidth .bw
								Set numeric value... .i RobustStd .std
								Set numeric value... .i MaxFreq .maxfreq
								Set numeric value... .i F1b .tmp_res[1]
								Set numeric value... .i F2b .tmp_res[2]
								Set numeric value... .i F3b .tmp_res[3]
								Set numeric value... .i B1b .tmp_res[4]
								Set numeric value... .i B2b .tmp_res[5]
								Set numeric value... .i B3b .tmp_res[6]
								Set numeric value... .i F1r analyzeFormants.res[1]
								Set numeric value... .i F2r analyzeFormants.res[2]
								Set numeric value... .i F3r analyzeFormants.res[3]
								Set numeric value... .i B1r analyzeFormants.res[4]
								Set numeric value... .i B2r analyzeFormants.res[5]
								Set numeric value... .i B3r analyzeFormants.res[6]				
							#endfor

							#clean the last generated vowel sound
							select createVowel.id
							Remove
						endfor
					endfor
				#endfor
			endfor
		endfor
	endfor
	select .pols
	Remove
endproc


##################
# analyze procedure
##################
procedure analyzeFormants .sndid .max_freq .std_dev .start .end
#use the burg version if std_dev is 0 otherwise use the robust method
	select .sndid
	
	#call burg formant analyzer
	if .std_dev = 0
		noprogress To Formant (burg)... 0.0 5 .max_freq 0.025 50
	else
		noprogress To Formant (robust)... 0.0 5 .max_freq 0.025 50 .std_dev 5 0.000001
	endif

	.res[1] = Get mean... 1 .start .end Hertz
	.res[2] = Get mean... 2 .start .end Hertz
	.res[3] = Get mean... 3 .start .end Hertz
	.res[4] = Get quantile of bandwidth... 1 .start .end Hertz 0.5
	.res[5] = Get quantile of bandwidth... 2 .start .end Hertz 0.5
	.res[6] = Get quantile of bandwidth... 3 .start .end Hertz 0.5
	Remove
endproc

##################
# create a vowel procedure
##################
procedure createVowel .type .nrformants .src_freq .f1_freq .f1_bw .f2_freq .f2_bw .f3_freq .f3_bw .f4_freq .f5_freq
	#create the vowel
	tmpid[1] = Create PitchTier... tmp 0.0 0.3
	Add point... 0.5 .src_freq
	
	if .type = 0
		tmpid[2] = To Sound (pulse train)... 44100 1.0 0.05 2000 off
	else
		tmpid[2] = To Sound (phonation)... 44100 1.0 0.05 0.7 0.03 3.0 4.0 off
	endif

	tmpid[3] = Filter (one formant)... .f1_freq .f1_bw
	tmpid[4] = Filter (one formant)... .f2_freq .f2_bw
	if .nrformants = 3
	 	.id = Filter (one formant)... .f3_freq .f3_bw
	elif .nrformants = 4
		tmpid[5] = Filter (one formant)... .f3_freq .f3_bw
		.id = Filter (one formant)... .f4_freq 0.1*.f4_freq
	elif .nrformants = 5
		tmpid[5] = Filter (one formant)... .f3_freq .f3_bw
		tmpid[6] = Filter (one formant)... .f4_freq 0.1*.f4_freq
		.id = Filter (one formant)... .f5_freq 0.1*.f5_freq
	endif

	#clean old
	select tmpid[1]
	plus tmpid[2]
	plus tmpid[3]
	plus tmpid[4]
	if .nrformants >= 4
		plus tmpid[5]
	endif
	if .nrformants = 5
		plus tmpid[6]
	endif
	Remove
endproc

